﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices; 

namespace LLK_WG
{
    class Class1
    {
        #region 引用API函数
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern IntPtr FindWindow(string strClass, string strWindow);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern int GetWindowRect(IntPtr hwnd, ref RECT lpRect);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern int SetCursorPos(int x, int y);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool GetCursorPos(ref POINT lpPoint);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern int SetForegroundWindow(IntPtr hwnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
        public const int MOUSEEVENTF_LEFTDOWN = 0x2;
        public const int MOUSEEVENTF_LEFTUP = 0x4;

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern int GetWindowThreadProcessId(IntPtr id, out int pid);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
        public const int PROCESS_ALL_ACCESS = 0x1F0FFF; //0x001F0FFF;
        public const int PROCESS_VM_OPERATION = 0x0008;
        public const int PROCESS_VM_READ = 0x0010;
        public const int PROCESS_VM_WRITE = 0x0020;

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int CloseHandle(IntPtr hProcess);

        [DllImport("Kernel32.dll")]
        public static extern uint GetLastError();

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, out int lpBuffer, int nSize, out int lpNumberOfBytesRead);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[,] lpBuffer, int nSize, out int lpNumberOfBytesRead);
        //hProcess为远程进程的句柄
        //lpBaseAddress用于指明远程进程中的地址
        //lpBuffer是本地进程中的内存地址
        //nSize是需要传送的字节数
        //lpNumberOfBytesRead和lpNumberOfBytesWritten用于指明实际传送的字节数.当函数返回时，可以查看这两个参数的值

        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
        public const uint MouseDown = 0x201; // Left click down code 
        public const uint MouseUp = 0x202; // Left click up code 

        #endregion
        string gameCaption = "QQ游戏 - 连连看角色版";
        RECT rect1;
        string aa = "";      
        IntPtr h;
        string[,] bb = new string[11, 19];
        //ChessPoint cp = new ChessPoint();
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }
        public struct POINT
        {
            public int x;
            public int y;
        }
        public POINT up(POINT pxy)
        {
            POINT up = pxy;
            up.y = pxy.y -1;
            return up;
        }
        public POINT down(POINT pxy)
        {
            POINT down = pxy;
            down.y = pxy.y +1;
            return down;
        }
        public POINT left(POINT pxy)
        {
            POINT left = pxy;
            left.x = pxy.x - 1;
            return left;
        }
        public POINT right(POINT pxy)
        {
            POINT right = pxy;
            right.x = pxy.x + 1;
            return right;
        }
        public POINT p(POINT pxy)
        {
            POINT p = pxy;
            return p;
        }
        public void startGame()
        {
            IntPtr h;
            h = FindWindow(null, gameCaption);
            if (h.ToInt32() != 0)
            {
                POINT p1 = new POINT(); ;
                GetCursorPos(ref p1);
                GetWindowRect(h, ref rect1);
                SetCursorPos(660 + rect1.Left, 566 + rect1.Top);
                SetForegroundWindow(h);
                mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
                mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
                SetCursorPos(p1.x, p1.y);
            }
        }
        public string readChessDate()
        {           
            byte[,] vBuffer = new byte[11, 19];
            aa = "";
            h = FindWindow(null, gameCaption);//获取窗口句柄
            if (h.ToInt32() != 0)
            {
                int pID = 0;
                // int addr = 0x0012A3F8; // xp
                int addr = 0x0018A3BC;   //win 7 64bit
                int dwProcessId = GetWindowThreadProcessId(h, out pID);
                IntPtr hProces = OpenProcess(PROCESS_ALL_ACCESS, false, pID);
                uint er = GetLastError();
                int readByte;
                ReadProcessMemory((int)hProces, addr, vBuffer, 11 * 19, out readByte);
                for (int i = 0; i < 11; i++)
                {
                    for (int a = 0; a < 19; a++)
                    {
                        aa = aa + vBuffer[i, a].ToString();
                        aa += " ";
                    }
                    aa += ("\r\n");
                }
            }
            return aa;
        }
        public string readSite()
        {
            string site = "";
            byte[] vBuffer = new byte[4];
            IntPtr vBytesAddress = Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0); // 得到缓冲区的地址         
            IntPtr h;
            h = FindWindow(null, gameCaption);//获取窗口句柄
            if (h.ToInt32() != 0)
            {

                int pID = 0;
                //uint hProces = 0;
                int addr = 0x001127D4;
                IntPtr hToken = IntPtr.Zero;

                int dwProcessId = GetWindowThreadProcessId(h, out pID);
                IntPtr hProces = OpenProcess(PROCESS_ALL_ACCESS, false, pID);
                uint er = GetLastError();
                int dataAddress;
                int readByte;

                ReadProcessMemory((int)hProces, addr, out dataAddress, 1, out readByte);
                site = dataAddress.ToString();
            }
            return site;
        }
        public void clickFirst()
        {
            h = FindWindow(null, gameCaption);
            if (h.ToInt32() != 0)
            {
                int x = 22;
                int y = 187;
                POINT p1 = new POINT();
                GetCursorPos(ref p1);
                mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
                mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
                IntPtr lParam = (IntPtr)((y << 16) | x); // The coordinates 
                IntPtr wParam = IntPtr.Zero; // Additional parameters for the click (e.g. Ctrl) 
                SendMessage(h, MouseDown, wParam, lParam); // Mouse button down 
                SendMessage(h, MouseUp, wParam, lParam); // Mouse button up 
                SetCursorPos(p1.x, p1.y);
            }
        }
        public string[,] updateChessDate()
        {
            string [,] bb=new string[11,19];
            byte[,] vBuffer = new byte[11, 19];
            h = FindWindow(null, gameCaption);//获取窗口句柄
            if (h.ToInt32() != 0)
            {
                int pID = 0;
                int addr = 0x0018A3BC;
                int dwProcessId = GetWindowThreadProcessId(h, out pID);
                IntPtr hProces = OpenProcess(PROCESS_ALL_ACCESS, false, pID);
                int readByte;
                ReadProcessMemory((int)hProces, addr, vBuffer, 11 * 19, out readByte);
                  for (int i = 0; i < 11; i++)
                    {
                        for (int a = 0; a < 19; a++)
                        {
                            bb[i,a]=vBuffer[i,a].ToString();
                        } 
                    }
            }
            return bb;
        }
       
        public bool checkLine(POINT p1, POINT p2)   //判断两个点间是否可连线
        {
            bool OK=false;
            bb = updateChessDate();
            if ((p1.x == p2.x) && (p1.y == p2.y)) 
            {
                OK=true;
            }
            else if ((p1.y <0) || (p2.y < 0) || (p1.x <0) || (p2.x < 0) || (p1.y >10) || (p2.y >10) || (p1.x>18) || (p2.x>18))
            {
                OK=false;
            }
          //x坐标相同
            else if (p1.x == p2.x)
            {
                if (p1.y > p2.y)
                {
                    int t = p1.y; p1.y = p2.y; p2.y = t;
                }
                for (int y = p1.y; y <= p2.y; y++)
                {
                    if (int.Parse(bb[y, p1.x]) == 0)
                    {
                        OK = true;
                    }
                    else
                    {
                        OK = false;
                        break;
                    }
                }
            }
          //y坐标相同  
            else if (p1.y == p2.y)
            {
                if (p1.x > p2.x)
                {
                    int t = p1.x; p1.x = p2.x; p2.x = t;
                }
                for (int x = p1.x; x <= p2.x; x++)
                {
                    if (int.Parse(bb[p1.y, x]) == 0)
                    {
                        OK = true;
                    }
                    else
                    {
                        OK = false;
                        break;
                    }
                }
            }
            return OK;
        }

        public bool check2p(POINT p1, POINT p2)
        {
            bool OK=false;
            bb = updateChessDate();
            POINT p11, p22;
            p11 = p1; p22 = p2;
            if ((p1.x == p2.x) && (p1.y == p2.y))
            {
                OK = false;
            }
            //x坐标相同
            else if (p1.x == p2.x)
            {
                if (p2.y == p1.y + 1)
                {
                    OK = true;
                }
                else if (p1.y == p2.y + 1)
                {
                    OK = true;
                }
                else
                {   //检测左右
                    //x 左
                    p11 = p1; p22 = p2;
                    for (int x = 0; x <= left(p1).x; x++)
                    {
                        p11.x = x; p22.x = x;
                        if (checkLine(p11, left(p1)) && checkLine(p22, left(p2)) && checkLine(p11, p22))
                        {
                            OK = true;
                        }
                    }
                    //x 右
                    p11 = p1; p22 = p2;
                    for (int x = right(p1).x; x < 19; x++)
                    {
                        p11.x = x; p22.x = x;
                        if (checkLine(p11, right(p1)) && checkLine(p22, right(p2)) && checkLine(p11, p22))
                        {
                            OK = true;
                        }
                    }
                }
            }
            else if (p1.y == p2.y)//y坐标相同
            {
                if (p1.x == p2.x + 1)
                {
                    OK = true;
                }
                else if (p2.x == p1.x + 1)
                {
                    OK = true;
                }
                else
                {
                    //检测上下
                    //y 上
                    p11=p1;p22=p2;
                    if((up(p1).y>=0)&&(up(p1).y<11))
                    {
                        for(int y=0;y<=up(p1).y;y++)
                        {
                            p11.y=y;p22.y=y;
                            if(checkLine(p11,up(p1))&&checkLine(p22,up(p2))&&checkLine(p11,p22))
                            {
                                OK=true;
                            }
                        }
                    }
                    //y 下
                    p11 = p1; p22 = p2;
                    if ((down(p1).y >= 0) && (down(p1).y < 11))
                    {
                        for (int y = down(p1).y; y < 11; y++)
                        {
                            p11.y = y; p22.y = y;
                            if (checkLine(p11, down(p1)) && checkLine(p22, down(p2)) && checkLine(p11, p22))
                            {
                                OK = true;
                            }
                        }
                    }
                }
            }
            else
            {
                //p1.x>p2.x
                if (p1.x > p2.x)
                {
                    //p1.y<p2.y
                    for (int x = 0; x <p2.x; x++)
                    {
                        p11.x = x; p22.x = x;
                        if(checkLine(p11,left(p1))&&checkLine(p11,p22)&&checkLine(p22,left(p2)))
                        {
                            OK=true;
                        }
                    }
                    for(int x=p2.x;x<=p1.x;x++)
                    {
                        p11.x = x; p22.x = x;
                        if (checkLine(right(p2), p22) && checkLine(p11, p22) && checkLine(p11,left(p1)))
                        {
                            OK = true;
                        }
                    }
                    for (int x = right(p1).x; x < 19; x++)
                    {
                        p11.x = x; p22.x = x;
                        if(checkLine(right(p1),p11)&&checkLine(p11,p22)&&checkLine(right(p2),p22))
                        {
                            OK=true;
                        }
                    }
                    p11.x = p1.x; p22.x = p2.x;
                    for (int y = 0; y <= p1.y; y++)
                    {
                        p11.y = y; p22.y = y;
                        if (checkLine(p22, p11) && checkLine(p11, up(p1)) && checkLine(p22, up(p2)))
                        {
                            OK = true;
                        }
                    }
                    for (int y = down(p1).y; y <= p2.y; y++)
                    {
                        p11.y = y; p22.y = y;
                        if (checkLine(p22, p11) && checkLine(down(p1), p11) && checkLine(p22, up(p2)))
                        {
                            OK = true;
                        }
                    }
                    for (int y = down(p2).y; y < 11; y++)
                    {
                        p11.y = y; p22.y = y;
                        if (checkLine(p11, p22) && checkLine(down(p1), p11) && checkLine(up(p2), p22))
                        {
                            OK = true;
                        }
                    }   
                }
               
                else if (p1.x < p2.x)
                {
                    p11.y = p1.y; p22.y = p2.y;
                    for (int x = 0; x <= p1.x; x++)
                    {
                        p11.x = x; p22.x = x;
                        if (checkLine(p11, p22) && checkLine(p11, left(p1)) && checkLine(p22, left(p2)))
                        {
                            OK = true;
                        }
                    }
                    for (int x = right(p1).x; x <=p2.x; x++)
                    {
                        p11.x = x; p22.x = x;
                        if (checkLine(p11, p22) && checkLine(right(p1), p11) && checkLine(p22, left(p2)))
                        {
                            OK = true;
                        }
                    }
                    for (int x = right(p2).x; x < 19; x++)
                    {
                        p11.x = x; p22.x = x;
                        if (checkLine(p11, p22) && checkLine(right(p1), p11) && checkLine(right(p2), p22))
                        {
                            OK = true;
                        }
                    }
                    p11.x = p1.x; p22.x = p2.x;
                    if ((up(p1).y >= 0) && (up(p1).y < 11))
                    {
                        for (int y = 0; y <= up(p1).y; y++)
                        {
                            p11.y = y; p22.y = y;
                            if (checkLine(p11, p22) && checkLine(p11, up(p1)) && checkLine(p22, up(p2)))
                            {
                                OK = true;
                            }
                        }
                    }
                    p11.x = p1.x; p22.x = p2.x;
                    if((down(p1).y<11)&&(up(p2).y>=0))
                    {
                        for (int y = p1.y; y <= up(p2).y; y++)
                        {
                            p11.y = y; p22.y = y;
                            if (checkLine(p11, p22) && checkLine(down(p1), p11) && checkLine(p22, up(p2)))
                            {
                                OK = true;
                            }
                        }
                    }
                    p11.x = p1.x; p22.x = p2.x;
                    if (down(p2).y < 11)
                    {
                        for (int y = p2.y; y < 11; y++)
                        {
                            p11.y = y; p22.y = y;
                            if (checkLine(p11, p22) && checkLine(down(p1), p11) && checkLine(down(p2), p22))
                            {
                                OK = true;
                            }
                        }
                    }
                }
            }
            
            return OK;
        }

        public bool click2p(POINT p1,POINT p2)
        {
            h = FindWindow(null, gameCaption);
            if (h.ToInt32() != 0)
            {
                IntPtr lParam = (IntPtr)(((187+36*p1.y) << 16) | (22+31*p1.x)); // The coordinates 
                IntPtr wParam = IntPtr.Zero; // Additional parameters for the click (e.g. Ctrl) 
                SendMessage(h, MouseDown, wParam, lParam); // Mouse button down 
                SendMessage(h, MouseUp, wParam, lParam); // Mouse button up 
                lParam = (IntPtr)(((187 + 36 * p2.y) << 16) | (22 + 31 * p2.x));
                SendMessage(h, MouseDown, wParam, lParam); // Mouse button down 
                SendMessage(h, MouseUp, wParam, lParam); // Mouse button up 
            }
            return true;
        }
        public void clearPair()
        {
            //读出棋盘数据至chessdata 11,19
            bb = updateChessDate(); 
            //遍历整个棋盘 找出相同类型 一对棋子
            POINT p1, p2;
            int x1 = 0;
            int y1 = 0;
            int x2 = 0;
            int y2 = 0;
            for (y1 = 0; y1 < 11; y1++)
            {
                for (x1 = 0; x1 < 19; x1++)
                {
                    for (y2 = 0; y2 < 11; y2++)
                    {
                        for (x2 = 0; x2 < 19; x2++)
                        {
                            if ((bb[y1, x1] != null) && (int.Parse(bb[y1, x1]) != 0))
                            {
                                if (bb[y1, x1] == bb[y2, x2]) // 棋子1与棋子2 类型是否相同
                                {
                                    if (!((x1 == x2) && (y1 == y2)))
                                    {
                                        p1.x = x1; p1.y = y1;
                                        p2.x = x2; p2.y = y2;
                                        //检测 相同的2个棋子是否可消掉
                                        if (check2p(p1, p2))//如果可消除 则返回真
                                        {//click2p 鼠标模拟 点击 p1，p2
                                            click2p(p1, p2);
                                            return;
                                        }
                                    }
                                }
                            }
                        }
                    }
                   
                }
            }
        }
        public void clearAll()
        {
            //读出棋盘数据至chessdata 11,19
            bb = updateChessDate();
            //遍历整个棋盘 找出相同类型 一对棋子
            POINT p1, p2;
            int x1 = 0;
            int y1 = 0;
            int x2 = 0;
            int y2 = 0;
            for (y1 = 0; y1 < 11; y1++)
            {
                for (x1 = 0; x1 < 19; x1++)
                {
                    for (y2 = 0; y2 < 11; y2++)
                    {
                        for (x2 = 0; x2 < 19; x2++)
                        {
                            if ((bb[y1, x1] != null) && (int.Parse(bb[y1, x1]) != 0))
                            {
                                if (bb[y1, x1] == bb[y2, x2]) // 棋子1与棋子2 类型是否相同
                                {
                                    if (!((x1 == x2) && (y1 == y2)))
                                    {
                                        p1.x = x1; p1.y = y1;
                                        p2.x = x2; p2.y = y2;
                                        //检测 相同的2个棋子是否可消掉
                                        if (check2p(p1, p2))//如果可消除 则返回真
                                        {
                                            //click2p 鼠标模拟 点击 p1，p2
                                            click2p(p1, p2);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
     }
}